//! # 配置服务器 REST API
//!
//! 提供配置服务器的 HTTP REST API 接口，兼容 Spring Cloud Config 协议。
//!
//! ## API 路由
//!
//! * `GET /{application}/{profile}/{label}` - 获取配置
//! * `POST /{application}/{profile}/{label}` - 保存配置  
//! * `DELETE /{application}/{profile}/{label}` - 删除配置
//! * `GET /health` - 健康检查
//! * `GET /info` - 服务信息
//! * `GET /applications` - 获取应用列表
//! * `GET /{application}/profiles` - 获取环境列表
//! * `GET /{application}/{profile}/labels` - 获取标签列表
//! * `GET /{application}/{profile}/{label}/history` - 获取配置历史
//! * `POST /{application}/{profile}/{label}/rollback/{version}` - 回滚配置
//!
//! ## API 响应格式
//!
//! 所有API响应都遵循统一的JSON格式，并提供详细的错误信息和状态码。

use std::collections::HashMap;
use std::sync::Arc;

use axum::{
    extract::{Path, Query, State},
    http::StatusCode,
    response::{IntoResponse, Json},
    routing::{delete, get, post},
    Router,
};
use serde::{Deserialize, Serialize};
use serde_json::json;
use tower::ServiceBuilder;
use tower_http::{
    cors::CorsLayer,
    trace::TraceLayer,
    validate_request::ValidateRequestHeaderLayer,
};
use tracing::{error, info, warn};

use crate::RustCloudConfig;
use super::{
    ConfigServer, ConfigEnvironment, ConfigResponse, ConfigChangeRecord,
    ConfigServerError, Result,
};

/// API 响应包装器
#[derive(Debug, Serialize)]
#[serde(untagged)]
pub enum ApiResponse<T> {
    /// 成功响应
    Success(T),
    /// 错误响应
    Error {
        error: String,
        message: String,
        status: u16,
        timestamp: String,
    },
}

/// 健康检查响应
#[derive(Debug, Serialize)]
pub struct HealthResponse {
    pub status: String,
    pub components: HashMap<String, ComponentHealth>,
}

/// 组件健康状态
#[derive(Debug, Serialize)]
pub struct ComponentHealth {
    pub status: String,
    pub details: Option<HashMap<String, serde_json::Value>>,
}

/// 服务信息响应
#[derive(Debug, Serialize)]
pub struct InfoResponse {
    pub name: String,
    pub version: String,
    pub build_time: String,
    pub git_commit: Option<String>,
    pub uptime: u64,
    pub profiles: Vec<String>,
}

/// 保存配置请求
#[derive(Debug, Deserialize)]
pub struct SaveConfigRequest {
    pub config: RustCloudConfig,
    pub message: Option<String>,
}

/// 回滚配置请求  
#[derive(Debug, Deserialize)]
pub struct RollbackRequest {
    pub message: Option<String>,
}

/// 查询参数
#[derive(Debug, Deserialize)]
pub struct QueryParams {
    pub user: Option<String>,
    pub format: Option<String>, // json, yaml, toml
}

/// 应用状态
pub struct AppState {
    pub server: Arc<ConfigServer>,
    pub start_time: std::time::Instant,
}

/// 创建 API 路由
pub async fn create_routes(server: &ConfigServer) -> Result<Router> {
    let app_state = Arc::new(AppState {
        server: Arc::new(server.clone()),
        start_time: std::time::Instant::now(),
    });

    let app = Router::new()
        // 配置管理路由
        .route("/:application/:profile/:label", get(get_config_handler))
        .route("/:application/:profile/:label", post(save_config_handler))
        .route("/:application/:profile/:label", delete(delete_config_handler))
        
        // 配置历史和回滚
        .route("/:application/:profile/:label/history", get(get_config_history_handler))
        .route("/:application/:profile/:label/rollback/:version", post(rollback_config_handler))
        
        // 管理接口
        .route("/applications", get(list_applications_handler))
        .route("/:application/profiles", get(list_profiles_handler))
        .route("/:application/:profile/labels", get(list_labels_handler))
        
        // 系统接口
        .route("/health", get(health_check_handler))
        .route("/info", get(info_handler))
        .route("/metrics", get(metrics_handler))
        
        // 设置应用状态
        .with_state(app_state)
        
        // 添加中间件
        .layer(
            ServiceBuilder::new()
                .layer(TraceLayer::new_for_http())
                .layer(CorsLayer::permissive()) // 开发环境使用，生产环境需要配置具体的 CORS 策略
                .into_inner(),
        );

    Ok(app)
}

/// 获取配置处理器
async fn get_config_handler(
    State(state): State<Arc<AppState>>,
    Path((application, profile, label)): Path<(String, String, String)>,
    Query(params): Query<QueryParams>,
) -> impl IntoResponse {
    info!("📖 获取配置: {}:{}:{}", application, profile, label);

    let environment = ConfigEnvironment {
        application,
        profile,
        label,
        version: None,
        state: None,
    };

    match state.server.get_config(&environment).await {
        Ok(config) => {
            info!("✅ 配置获取成功");
            
            // 根据格式参数返回不同格式
            match params.format.as_deref() {
                Some("yaml") => {
                    // 返回 YAML 格式
                    match serde_yaml::to_string(&config) {
                        Ok(yaml) => (StatusCode::OK, yaml).into_response(),
                        Err(e) => create_error_response(
                            StatusCode::INTERNAL_SERVER_ERROR,
                            "序列化错误",
                            &e.to_string(),
                        ).into_response(),
                    }
                }
                Some("toml") => {
                    // 返回 TOML 格式
                    match toml::to_string(&config) {
                        Ok(toml_str) => (StatusCode::OK, toml_str).into_response(),
                        Err(e) => create_error_response(
                            StatusCode::INTERNAL_SERVER_ERROR,
                            "序列化错误",
                            &e.to_string(),
                        ).into_response(),
                    }
                }
                _ => {
                    // 默认返回 JSON 格式
                    Json(ApiResponse::Success(config)).into_response()
                }
            }
        }
        Err(ConfigServerError::ConfigNotFound { .. }) => {
            warn!("⚠️ 配置不存在");
            create_error_response(
                StatusCode::NOT_FOUND,
                "配置不存在",
                &format!("配置 {}:{}:{} 不存在", environment.application, environment.profile, environment.label),
            ).into_response()
        }
        Err(e) => {
            error!("❌ 获取配置失败: {}", e);
            create_error_response(
                StatusCode::INTERNAL_SERVER_ERROR,
                "获取配置失败",
                &e.to_string(),
            ).into_response()
        }
    }
}

/// 保存配置处理器
async fn save_config_handler(
    State(state): State<Arc<AppState>>,
    Path((application, profile, label)): Path<(String, String, String)>,
    Query(params): Query<QueryParams>,
    Json(request): Json<SaveConfigRequest>,
) -> impl IntoResponse {
    let user = params.user.unwrap_or_else(|| "anonymous".to_string());
    info!("💾 保存配置: {}:{}:{} by {}", application, profile, label, user);

    let environment = ConfigEnvironment {
        application,
        profile,
        label,
        version: None,
        state: None,
    };

    match state.server.save_config(&environment, &request.config, &user).await {
        Ok(version) => {
            info!("✅ 配置保存成功，版本: {}", version);
            Json(ApiResponse::Success(json!({
                "message": "配置保存成功",
                "version": version,
                "timestamp": chrono::Utc::now().to_rfc3339()
            }))).into_response()
        }
        Err(e) => {
            error!("❌ 保存配置失败: {}", e);
            create_error_response(
                StatusCode::INTERNAL_SERVER_ERROR,
                "保存配置失败",
                &e.to_string(),
            ).into_response()
        }
    }
}

/// 删除配置处理器
async fn delete_config_handler(
    State(state): State<Arc<AppState>>,
    Path((application, profile, label)): Path<(String, String, String)>,
    Query(params): Query<QueryParams>,
) -> impl IntoResponse {
    let user = params.user.unwrap_or_else(|| "anonymous".to_string());
    info!("🗑️ 删除配置: {}:{}:{} by {}", application, profile, label, user);

    let environment = ConfigEnvironment {
        application,
        profile,
        label,
        version: None,
        state: None,
    };

    match state.server.delete_config(&environment, &user).await {
        Ok(()) => {
            info!("✅ 配置删除成功");
            Json(ApiResponse::Success(json!({
                "message": "配置删除成功",
                "timestamp": chrono::Utc::now().to_rfc3339()
            }))).into_response()
        }
        Err(ConfigServerError::ConfigNotFound { .. }) => {
            warn!("⚠️ 配置不存在");
            create_error_response(
                StatusCode::NOT_FOUND,
                "配置不存在",
                "指定的配置文件不存在",
            ).into_response()
        }
        Err(e) => {
            error!("❌ 删除配置失败: {}", e);
            create_error_response(
                StatusCode::INTERNAL_SERVER_ERROR,
                "删除配置失败",
                &e.to_string(),
            ).into_response()
        }
    }
}

/// 获取配置历史处理器
async fn get_config_history_handler(
    State(state): State<Arc<AppState>>,
    Path((application, profile, label)): Path<(String, String, String)>,
) -> impl IntoResponse {
    info!("📋 获取配置历史: {}:{}:{}", application, profile, label);

    let environment = ConfigEnvironment {
        application,
        profile,
        label,
        version: None,
        state: None,
    };

    match state.server.get_storage().get_config_history(&environment).await {
        Ok(history) => {
            info!("✅ 获取配置历史成功，共 {} 条记录", history.len());
            Json(ApiResponse::Success(history)).into_response()
        }
        Err(e) => {
            error!("❌ 获取配置历史失败: {}", e);
            create_error_response(
                StatusCode::INTERNAL_SERVER_ERROR,
                "获取配置历史失败",
                &e.to_string(),
            ).into_response()
        }
    }
}

/// 回滚配置处理器
async fn rollback_config_handler(
    State(state): State<Arc<AppState>>,
    Path((application, profile, label, version)): Path<(String, String, String, String)>,
    Query(params): Query<QueryParams>,
    Json(_request): Json<RollbackRequest>,
) -> impl IntoResponse {
    let user = params.user.unwrap_or_else(|| "anonymous".to_string());
    info!("🔄 回滚配置: {}:{}:{} 到版本 {} by {}", application, profile, label, version, user);

    let environment = ConfigEnvironment {
        application,
        profile,
        label,
        version: None,
        state: None,
    };

    match state.server.get_storage().rollback_config(&environment, &version, &user).await {
        Ok(()) => {
            info!("✅ 配置回滚成功");
            Json(ApiResponse::Success(json!({
                "message": "配置回滚成功",
                "version": version,
                "timestamp": chrono::Utc::now().to_rfc3339()
            }))).into_response()
        }
        Err(e) => {
            error!("❌ 配置回滚失败: {}", e);
            create_error_response(
                StatusCode::INTERNAL_SERVER_ERROR,
                "配置回滚失败",
                &e.to_string(),
            ).into_response()
        }
    }
}

/// 获取应用列表处理器
async fn list_applications_handler(
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    info!("📋 获取应用列表");

    match state.server.get_storage().list_applications().await {
        Ok(applications) => {
            info!("✅ 获取应用列表成功，共 {} 个应用", applications.len());
            Json(ApiResponse::Success(applications)).into_response()
        }
        Err(e) => {
            error!("❌ 获取应用列表失败: {}", e);
            create_error_response(
                StatusCode::INTERNAL_SERVER_ERROR,
                "获取应用列表失败",
                &e.to_string(),
            ).into_response()
        }
    }
}

/// 获取环境列表处理器
async fn list_profiles_handler(
    State(state): State<Arc<AppState>>,
    Path(application): Path<String>,
) -> impl IntoResponse {
    info!("📋 获取应用 {} 的环境列表", application);

    match state.server.get_storage().list_profiles(&application).await {
        Ok(profiles) => {
            info!("✅ 获取环境列表成功，共 {} 个环境", profiles.len());
            Json(ApiResponse::Success(profiles)).into_response()
        }
        Err(e) => {
            error!("❌ 获取环境列表失败: {}", e);
            create_error_response(
                StatusCode::INTERNAL_SERVER_ERROR,
                "获取环境列表失败",
                &e.to_string(),
            ).into_response()
        }
    }
}

/// 获取标签列表处理器
async fn list_labels_handler(
    State(state): State<Arc<AppState>>,
    Path((application, profile)): Path<(String, String)>,
) -> impl IntoResponse {
    info!("📋 获取应用 {}:{} 的标签列表", application, profile);

    match state.server.get_storage().list_labels(&application, &profile).await {
        Ok(labels) => {
            info!("✅ 获取标签列表成功，共 {} 个标签", labels.len());
            Json(ApiResponse::Success(labels)).into_response()
        }
        Err(e) => {
            error!("❌ 获取标签列表失败: {}", e);
            create_error_response(
                StatusCode::INTERNAL_SERVER_ERROR,
                "获取标签列表失败",
                &e.to_string(),
            ).into_response()
        }
    }
}

/// 健康检查处理器
async fn health_check_handler(
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    info!("🏥 健康检查");

    let mut components = HashMap::new();
    
    // 检查Git存储健康状态
    let git_health = match state.server.get_storage().list_applications().await {
        Ok(_) => ComponentHealth {
            status: "UP".to_string(),
            details: Some({
                let mut details = HashMap::new();
                details.insert("type".to_string(), json!("git"));
                details
            }),
        },
        Err(_) => ComponentHealth {
            status: "DOWN".to_string(),
            details: Some({
                let mut details = HashMap::new();
                details.insert("error".to_string(), json!("Git存储连接失败"));
                details
            }),
        },
    };
    components.insert("storage".to_string(), git_health);

    // 检查加密组件
    if state.server.get_encryption().is_some() {
        components.insert("encryption".to_string(), ComponentHealth {
            status: "UP".to_string(),
            details: Some({
                let mut details = HashMap::new();
                details.insert("type".to_string(), json!("aes256"));
                details
            }),
        });
    }

    // 检查审计组件
    if state.server.get_audit().is_some() {
        components.insert("audit".to_string(), ComponentHealth {
            status: "UP".to_string(),
            details: None,
        });
    }

    let overall_status = if components.values().all(|c| c.status == "UP") {
        "UP"
    } else {
        "DOWN"
    };

    let health = HealthResponse {
        status: overall_status.to_string(),
        components,
    };

    Json(ApiResponse::Success(health)).into_response()
}

/// 服务信息处理器
async fn info_handler(
    State(state): State<Arc<AppState>>,
) -> impl IntoResponse {
    info!("ℹ️ 获取服务信息");

    let uptime = state.start_time.elapsed().as_secs();
    
    let info = InfoResponse {
        name: "RustCloud Config Server".to_string(),
        version: env!("CARGO_PKG_VERSION").to_string(),
        build_time: std::env::var("BUILD_TIME").unwrap_or_else(|_| "unknown".to_string()),
        git_commit: option_env!("GIT_COMMIT").map(|s| s.to_string()),
        uptime,
        profiles: vec!["default".to_string(), "dev".to_string(), "test".to_string(), "prod".to_string()],
    };

    Json(ApiResponse::Success(info)).into_response()
}

/// 指标处理器
async fn metrics_handler(
    State(_state): State<Arc<AppState>>,
) -> impl IntoResponse {
    info!("📊 获取服务指标");

    // 这里可以集成 Prometheus 指标
    let metrics = r#"# HELP config_server_requests_total Total number of requests
# TYPE config_server_requests_total counter
config_server_requests_total{method="GET",endpoint="/health"} 100
config_server_requests_total{method="GET",endpoint="/info"} 50
config_server_requests_total{method="GET",endpoint="/config"} 200

# HELP config_server_configs_total Total number of configurations
# TYPE config_server_configs_total gauge
config_server_configs_total 25

# HELP config_server_uptime_seconds Server uptime in seconds
# TYPE config_server_uptime_seconds gauge
config_server_uptime_seconds 3600
"#;

    (
        StatusCode::OK,
        [("content-type", "text/plain; version=0.0.4")],
        metrics,
    ).into_response()
}

/// 创建错误响应
fn create_error_response(
    status: StatusCode,
    error: &str,
    message: &str,
) -> Json<ApiResponse<()>> {
    Json(ApiResponse::Error {
        error: error.to_string(),
        message: message.to_string(),
        status: status.as_u16(),
        timestamp: chrono::Utc::now().to_rfc3339(),
    })
}

/// 配置服务器的Clone实现
impl Clone for ConfigServer {
    fn clone(&self) -> Self {
        Self {
            config: self.config.clone(),
            storage: self.storage.clone(),
            encryption: self.encryption.clone(),
            audit: self.audit.clone(),
            permission: self.permission.clone(),
            cache: self.cache.clone(),
        }
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use axum::http::StatusCode;
    use axum_test::TestServer;

    #[tokio::test]
    async fn test_health_check() {
        // 这里需要创建一个测试用的ConfigServer实例
        // let server = create_test_server().await;
        // let app = create_routes(&server).await.unwrap();
        // let test_server = TestServer::new(app).unwrap();
        
        // let response = test_server.get("/health").await;
        // assert_eq!(response.status_code(), StatusCode::OK);
    }

    #[tokio::test] 
    async fn test_info_endpoint() {
        // 类似的测试实现
    }
}